clear;
clc;
close all;
QAMary = 16;
fftSize = 2048;
SNR = 50;
MaxDopplerFrec = 500; 
JakesFilterCoeff = 201; 
userType=1;
CodeRate=1/2;
n_bits = log2(QAMary);
nSymbols = 48;
NoPilots=(fftSize-((fftSize/(256/23))*2))/7;
pilots=sqrt(2)*(floor(rand(NoPilots,1)*2)*2-1);
preamble=zeros(fftSize,1);
Npilotos=fftSize/(256/23);
Soft=1;
N0=1;


%Preamble
nopreamble=zeros(fftSize-(Npilotos+Npilotos-1),1);
k=1;
for i=1:fftSize
   if((i<=Npilotos)||(i>(fftSize-Npilotos))||(i==(fftSize)/2) ) 
       preamble(i,1)=complex(0,0);
   else
       preamble(i,1)=sqrt(2)*(floor(rand(1)*2)*2-1);
       nopreamble(k)=i;
       k=k+1;
   end
    
end



%Channel
JakesFilter_Fs=(48)/.005;
f=linspace(0,JakesFilter_Fs,JakesFilter_Fs-1);
JFILTER = 1/(4*pi)*1./(MaxDopplerFrec.*sqrt(1-(f./MaxDopplerFrec).^2));
JFILTER(f>MaxDopplerFrec)=0;
f2=linspace(0,1,JakesFilter_Fs-1);
JFilter = fir2(JakesFilterCoeff,f2,JFILTER);
JFilter = JFilter/sqrt(sum((abs(JFilter)).^2));

taps_power = [0 -1 -9 -10 -15 -20;              %User Type 1
              0 -9.7 -192 -22.8 -10^3 -10^3   %User Type 2
              0 -.9 -4.9 -8 -7.8 -23.9];        %User Type 3
          
tapsnzeros = zeros(5,3,3); %fftSize(512,1024,2048), UserType(1,2,3),           
%2048 sampling based
tapsnzeros(:,3,1) = [6 8 7 13 17]; %User 1 Zeros in Channel fftSize 2048
tapsnzeros(:,3,2) = [1 1 4 1 1]; %User 2 Zeros in Channel fftSize 2048
tapsnzeros(:,3,3) = [4 12 8 23 30]; %User 3 Zeros in Channel fftSize 2048
%1024 sampling based
tapsnzeros(:,2,1) = [3 3 3 6 8]; %User 1 Zeros in Channel fftSize 1024
tapsnzeros(:,2,2) = [0 0 2 1 1]; %User 2 Zeros in Channel fftSize 1024
tapsnzeros(:,2,3) = [1 6 2 13 14]; %User 3 Zeros in Channel fftSize 1024
%512 sampling based
%tapsnzeros(:,3,1) = [6 8 7 13 17]; %User 1 Zeros in Channel fftSize 2048
%tapsnzeros(:,3,2) = [1 1 4 1 1]; %User 2 Zeros in Channel fftSize 2048
%tapsnzeros(:,3,3) = [4 12 8 23 30]; %User 3 Zeros in Channel fftSize 2048


taps_nzerosSelect=tapsnzeros(:,3,userType);
taps_selec = taps_power(userType,:);

switch QAMary
    case 4
    QAM  = [-0.707106781186548 + 0.707106781186548i;-0.707106781186548 - 0.707106781186548i;0.707106781186548 + 0.707106781186548i;0.707106781186548 - 0.707106781186548i;]; 
    case 16
    QAM = [-0.948683298050514 + 0.948683298050514i;-0.948683298050514 + 0.316227766016838i;-0.948683298050514 - 0.948683298050514i;-0.948683298050514 - 0.316227766016838i;-0.316227766016838 + 0.948683298050514i;-0.316227766016838 + 0.316227766016838i;-0.316227766016838 - 0.948683298050514i;-0.316227766016838 - 0.316227766016838i;0.948683298050514 + 0.948683298050514i;0.948683298050514 + 0.316227766016838i;0.948683298050514 - 0.948683298050514i;0.948683298050514 - 0.316227766016838i;0.316227766016838 + 0.948683298050514i;0.316227766016838 + 0.316227766016838i;0.316227766016838 - 0.948683298050514i;0.316227766016838 - 0.316227766016838i;];
    case 64
    QAM=[-1.08012344973464 + 1.08012344973464i;-1.08012344973464 + 0.771516749810460i;-1.08012344973464 + 0.154303349962092i;-1.08012344973464 + 0.462910049886276i;-1.08012344973464 - 1.08012344973464i;-1.08012344973464 - 0.771516749810460i;-1.08012344973464 - 0.154303349962092i;-1.08012344973464 - 0.462910049886276i;-0.771516749810460 + 1.08012344973464i;-0.771516749810460 + 0.771516749810460i;-0.771516749810460 + 0.154303349962092i;-0.771516749810460 + 0.462910049886276i;-0.771516749810460 - 1.08012344973464i;-0.771516749810460 - 0.771516749810460i;-0.771516749810460 - 0.154303349962092i;-0.771516749810460 - 0.462910049886276i;-0.154303349962092 + 1.08012344973464i;-0.154303349962092 + 0.771516749810460i;-0.154303349962092 + 0.154303349962092i;-0.154303349962092 + 0.462910049886276i;-0.154303349962092 - 1.08012344973464i;-0.154303349962092 - 0.771516749810460i;-0.154303349962092 - 0.154303349962092i;-0.154303349962092 - 0.462910049886276i;-0.462910049886276 + 1.08012344973464i;-0.462910049886276 + 0.771516749810460i;-0.462910049886276 + 0.154303349962092i;-0.462910049886276 + 0.462910049886276i;-0.462910049886276 - 1.08012344973464i;-0.462910049886276 - 0.771516749810460i;-0.462910049886276 - 0.154303349962092i;-0.462910049886276 - 0.462910049886276i;1.08012344973464 + 1.08012344973464i;1.08012344973464 + 0.771516749810460i;1.08012344973464 + 0.154303349962092i;1.08012344973464 + 0.462910049886276i;1.08012344973464 - 1.08012344973464i;1.08012344973464 - 0.771516749810460i;1.08012344973464 - 0.154303349962092i;1.08012344973464 - 0.462910049886276i;0.771516749810460 + 1.08012344973464i;0.771516749810460 + 0.771516749810460i;0.771516749810460 + 0.154303349962092i;0.771516749810460 + 0.462910049886276i;0.771516749810460 - 1.08012344973464i;0.771516749810460 - 0.771516749810460i;0.771516749810460 - 0.154303349962092i;0.771516749810460 - 0.462910049886276i;0.154303349962092 + 1.08012344973464i;0.154303349962092 + 0.771516749810460i;0.154303349962092 + 0.154303349962092i;0.154303349962092 + 0.462910049886276i;0.154303349962092 - 1.08012344973464i;0.154303349962092 - 0.771516749810460i;0.154303349962092 - 0.154303349962092i;0.154303349962092 - 0.462910049886276i;0.462910049886276 + 1.08012344973464i;0.462910049886276 + 0.771516749810460i;0.462910049886276 + 0.154303349962092i;0.462910049886276 + 0.462910049886276i;0.462910049886276 - 1.08012344973464i;0.462910049886276 - 0.771516749810460i;0.462910049886276 - 0.154303349962092i;0.462910049886276 - 0.462910049886276i;];
    
    otherwise
    QAM = zeros(64,1);
end


DC=fftSize/2;
    NoPilots=(fftSize-((fftSize/(256/23))*2))/7;
    P=fftSize-NoPilots;

    pilotsIndexes1=zeros(fftSize,1);
    pilotsIndexes2=zeros(fftSize,1);
    pilotIndex1=zeros(fftSize,1);
    pilotIndex2=zeros(fftSize,1);
    index1=[0 0 0 0 1 0 0 0 1 0 0 0 0 0];
    index2=[1 0 0 0 0 0 0 0 0 0 0 0 1 0];
    j=1;

    for i=Npilotos+1:DC
        pilotIndex1(i)=index1(j);
        pilotIndex2(i)=index2(j);

        pilotIndex1(i-Npilotos+DC)=index1(j);
        pilotIndex2(i-Npilotos+DC)=index2(j);
        j=j+1;
        if j==15;
            j=1;
        end
    end
   
    j=1;
    k=1;
    for i=1:fftSize
       if(pilotIndex1(i)==0)
        pilotsIndexes1(i,1)=j;
        j=j+1;
       else
        pilotsIndexes1(i,1)=P+k;
        k=k+1;
       end
    end

    j=1;
    k=1;
    for i=1:fftSize
       if(pilotIndex2(i)==0)
        pilotsIndexes2(i,1)=j;
        j=j+1;
       else
        pilotsIndexes2(i,1)=P+k;
        k=k+1;
       end
    end
            pilots1=find(pilotIndex1);
            pilots2=find(pilotIndex2);

            pilots1n=find(~pilotIndex1);
            pilots2n=find(~pilotIndex2);
            
            pIndex1=pilotsIndexes1;    
            pIndex2=pilotsIndexes2;   
            
            pIndex1n=[pilots1n',pilots1']';
            pIndex2n=[pilots2n',pilots2']';

[perm_a,inv_a,perm_b,inv_b] = gen_perm_matrix(pilotIndex1,pilotIndex2,fftSize);

const_group;
